home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / Database / SimpleTableView-1 / BoolFormatter.m < prev    next >
Text File  |  1995-06-12  |  8KB  |  280 lines

  1. // -------------------------------------------------------------------------------------
  2. //    BooleanFormatter.h
  3. //  This software is without warranty of any kind.  Use at your own risk.
  4. // -------------------------------------------------------------------------------------
  5.  
  6. #import <objc/objc.h>
  7. #import <appkit/appkit.h>
  8. #import <mach/mach.h>
  9. #import <dbkit/dbkit.h>
  10. #import "BoolFormatter.h"
  11.  
  12. // -------------------------------------------------------------------------------------
  13. // NXRect abbreviations
  14. #define    X                    origin.x
  15. #define    Y                    origin.y
  16. #define    W                    size.width
  17. #define    H                    size.height
  18.  
  19. // -------------------------------------------------------------------------------------
  20. // drawCell image flags
  21. #define    hideIMAGEMASK        1
  22. #define    hideAltIMAGEMASK    2
  23. #define    hideIMAGE            ([drawCell tag] & hideIMAGEMASK)
  24. #define    hideAltIMAGE        ([drawCell tag] & hideAltIMAGEMASK)
  25. #define setHideIMAGE(X)        [drawCell setTag:(hideAltIMAGE | ((X)? 0 : hideIMAGEMASK))];
  26. #define setHideAltIMAGE(X)    [drawCell setTag:(hideIMAGE | ((X)? 0 : hideAltIMAGEMASK))];
  27.  
  28. // -------------------------------------------------------------------------------------
  29. @implementation BoolFormatter
  30.  
  31. // -------------------------------------------------------------------------------------
  32. // initialization
  33.  
  34. /* init */
  35. - init
  36. {
  37.  
  38.     /* init */
  39.     [super init];
  40.     selectionMode = NX_HIGHLIGHTMODE;
  41.     newValue = [[DBValue allocFromZone:[self zone]] init];
  42.     
  43.     /* drawing cell */
  44.     drawCell = [[ButtonCell allocFromZone:[self zone]] initIconCell:""];
  45.     [drawCell setBordered:NO];
  46.     [drawCell setIconPosition:NX_ICONONLY];
  47.     [drawCell setType:NX_TOGGLE];
  48.     [drawCell setIcon:"NXswitch"];
  49.     [drawCell setAltIcon:"NXswitchH"];
  50.     [drawCell setTag:0];
  51.     
  52.     return self;
  53. }
  54.  
  55. /* free */
  56. - free
  57. {
  58.     [newValue free];
  59.     [drawCell free];
  60.     return[super free];
  61. }
  62.  
  63. // -------------------------------------------------------------------------------------
  64. // set attributes
  65.  
  66. /* set mode */
  67. - setMode:(int)newMode
  68. {
  69.     selectionMode = newMode;
  70.     return self;
  71. }
  72.  
  73. /* return mode */
  74. - (int)mode
  75. {
  76.     return selectionMode;
  77. }
  78.  
  79. // -------------------------------------------------------------------------------------
  80. // images
  81.  
  82. /* set unselected image */
  83. - setImage:anImage
  84. {
  85.     setHideIMAGE(anImage);
  86.     return [drawCell setImage:anImage];
  87. }
  88.  
  89. /* return unselected image */
  90. - image
  91. {
  92.     return hideIMAGE? (id)nil : [drawCell image];
  93. }
  94.  
  95. /* set unselected image */
  96. - setIcon:(const char*)anIcon
  97. {
  98.     setHideIMAGE(anIcon && *anIcon);
  99.     return [drawCell setIcon:anIcon];
  100. }
  101.  
  102. /* return unselected image */
  103. - (const char*)icon
  104. {
  105.     return hideIMAGE? (char*)nil : [drawCell icon];
  106. }
  107.  
  108. /* set selected image */
  109. - setAltImage:anImage
  110. {
  111.     setHideAltIMAGE(anImage);
  112.     return [drawCell setAltImage:anImage];
  113. }
  114.  
  115. /* return selected image */
  116. - altImage
  117. {
  118.     return hideAltIMAGE? (id)nil : [drawCell altImage];
  119. }
  120.  
  121. /* set unselected image */
  122. - setAltIcon:(const char*)anIcon
  123. {
  124.     setHideAltIMAGE(anIcon && *anIcon);
  125.     return [drawCell setAltIcon:anIcon];
  126. }
  127.  
  128. /* return unselected image */
  129. - (const char*)altIcon
  130. {
  131.     return hideAltIMAGE? (char*)nil : [drawCell altIcon];
  132. }
  133.  
  134. // -------------------------------------------------------------------------------------
  135. // drawing
  136.  
  137. /* draw DBTableView field cell */
  138. - drawFieldAt:(u_int)row :(u_int)col inside:(NXRect*)frame inView:view
  139.     withAttributes:(id <DBTableVectors>)ra :(id <DBTableVectors>)ca
  140.     usePositions:(BOOL)ur :(BOOL)uc;
  141. {
  142.     BOOL    boolState;
  143.  
  144.     /* cache value and set state */
  145.     [self getValueAt:row:col withAttributes:ra:ca usePositions:ur:uc];
  146.     boolState = ([value isNull] || (*[value stringValue] == 'N'))? NO : YES;
  147.     [drawCell setState:boolState];
  148.     
  149.     /* draw image (if there is an image to draw) */
  150.     if (!((boolState && hideAltIMAGE) || (!boolState && hideIMAGE))) {
  151.         [drawCell setAlignment:[(([ra formatter]==self)?ra:ca) contentAlignment]];
  152.         [drawCell drawInside:frame inView:[NXApp focusView]];
  153.     }
  154.  
  155.     return self;
  156. }
  157.  
  158. // -------------------------------------------------------------------------------------
  159. // event monitoring
  160.  
  161. /* grab mouse-down to check for toggle value */
  162. - mouseDown:(NXEvent*)e at:(int)row:(int)col inside:(NXRect*)frame inView:(View*)view
  163.     withAttributes:(id <DBTableVectors>)ra:(id <DBTableVectors>)ca
  164.     usePositions:(BOOL)ur:(BOOL)uc
  165. {
  166.     id    lv, vw;
  167.  
  168.     /* ignore if not a double click */
  169.     if (e->data.mouse.click < 2) return (id)nil;
  170.  
  171.     if (selectionMode == NX_RADIOMODE) {    // radio mode (not fully tested)
  172.         int ndx;
  173.         
  174.         /* clear all other row values */
  175.         [newValue setStringValue:"NO"];
  176.         for (ndx = 0; ndx < [dataSource rowCount]; ndx++) {
  177.             if (ndx == row) continue;
  178.             [self getValueAt:ndx:col withAttributes:ra:ca usePositions:ur:uc];
  179.             if ((*[value stringValue] != 'N') &&
  180.                 (![self setValueAt:ndx:col withAttributes:ra:ca usePositions:ur:uc]))
  181.                     return (id)nil;
  182.         }
  183.  
  184.         /* get requested row value and re-set it to true */
  185.         [self getValueAt:row:col withAttributes:ra:ca usePositions:ur:uc];
  186.         if ([value isNull] || (*[value stringValue] == 'N')) {
  187.             [newValue setStringValue:"YES"];
  188.             [self setValueAt:row:col withAttributes:ra:ca usePositions:ur:uc];
  189.         }
  190.         
  191.     } else {    // list mode
  192.     
  193.         /* toggle value */
  194.         [self getValueAt:row:col withAttributes:ra:ca usePositions:ur:uc];
  195.         if ([value isNull] || (*[value stringValue] == 'N')) [newValue setStringValue:"YES"];
  196.         else [newValue setStringValue:"NO"];
  197.         [self setValueAt:row:col withAttributes:ra:ca usePositions:ur:uc];
  198.         
  199.     }
  200.  
  201.     /* redraw field (just tell DBTableView, if possible) */
  202.     for (lv = (id)nil, vw = view; vw && (lv != vw); lv = vw, vw = [vw superview]) {
  203.         if ([vw isKindOf:[DBTableView class]]) {
  204.             u_int r = ur? row : (u_int)[ra identifier];
  205.             [vw rowsChangedFrom:r to:r];
  206.             return self;
  207.         }
  208.     }
  209.     
  210.     /* slow redraw */
  211.     [self drawFieldAt:row:col inside:frame inView:view
  212.         withAttributes:ra:ca usePositions:ur:uc];
  213.     [view display];
  214.     [[view window] flushWindow];
  215.  
  216.     return self;
  217. }
  218.  
  219. // -------------------------------------------------------------------------------------
  220. // changing values
  221.  
  222. /* set field value */
  223. - setValueAt:(int)row :(int)col
  224.     withAttributes:(id <DBTableVectors>)ra :(id <DBTableVectors>)ca
  225.     usePositions:(BOOL)ur :(BOOL)uc
  226. {
  227.     u_int    c = uc? col : (u_int)[ca identifier];
  228.     u_int    r = ur? row : (u_int)[ra identifier];
  229.  
  230.     /* rows only */
  231.     if (ur && !uc) {
  232.         if ([delegate respondsTo:@selector(formatterWillChangeValueFor:at:to:sender:)] &&
  233.             ![delegate formatterWillChangeValueFor:(id)c at:r to:newValue sender:self])
  234.             return (id)nil;
  235.         [dataSource setValueFor:(id)c at:r from:newValue];
  236.         if ([delegate respondsTo:@selector(formatterDidChangeValueFor:at:to:sender:)])
  237.             [delegate formatterDidChangeValueFor:(id)c at:r to:newValue sender:self];
  238.         return self;
  239.     }
  240.     
  241.     /* columns only */
  242.     if (!ur && uc) {
  243.         if ([delegate respondsTo:@selector(formatterWillChangeValueFor:at:to:sender:)] &&
  244.             ![delegate formatterWillChangeValueFor:(id)r at:c to:newValue sender:self])
  245.             return (id)nil;
  246.         [dataSource setValueFor:(id)r at:c from:newValue];
  247.         if ([delegate respondsTo:@selector(formatterDidChangeValueFor:at:to:sender:)])
  248.             [delegate formatterDidChangeValueFor:(id)r at:c to:newValue sender:self];
  249.         return self;
  250.     }
  251.     
  252.     /* default */
  253.     if (![delegate formatterWillChangeValueFor:(id)r:(id)c to:newValue sender:self])
  254.         return (id)nil;
  255.     [dataSource setValueFor:(id)r:(id)c from:newValue];
  256.     if ([delegate respondsTo:@selector(formatterDidChangeValueFor::to:sender:)])
  257.         [delegate formatterDidChangeValueFor:(id)r:(id)c to:newValue sender:self];
  258.  
  259.     return self;
  260. }
  261.  
  262. // -------------------------------------------------------------------------------------
  263. // archiving
  264.  
  265. /* archive object to stream */
  266. - write:(NXTypedStream*) stream
  267. {
  268.     [super write:stream];
  269.     return self;
  270. }
  271.  
  272. /* read object from stream */
  273. - read:(NXTypedStream*) stream
  274. {
  275.     [super read:stream];
  276.     return self;
  277. }
  278.  
  279. @end
  280.